package com.gohi.core.service.impl;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.gohi.core.dao.IDAO;
import com.gohi.core.web.paging.PagingBean;

import com.gohi.main.util.Utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.TransactionException;

public class DefaultService<T,PK extends Serializable> {
	
	protected Log Log = LogFactory.getLog(getClass().getName());

	private DefaultServiceImpl<T,PK> DService;

	
	

	public DefaultServiceImpl<T,PK> getDService() {
		return DService;
	}

	public void setDService(DefaultServiceImpl<T,PK> dService) {
		DService = dService;
	}

	public IDAO<T,PK> getDAO() {
		return this.DService == null ? null : this.DService.getDAO();
	}


	/**
	 * 通过QueryMap查询数据列表
	 * <p>
	 * @param map
	 * 例：map.put("and param.like","%value%")
	 * <br>属性名.=	等于	
	 * <br>属性名.<>	不等于
	 * <br>属性名.like 模糊查询
	 * <br>属性名.in 	  
	 * <br>属性名.orderBy	排序 
	 * @param cls	实体类对象		例：ClassObject.class
	 * </p>
	 * @return 数据集合
	 * @author 曹湘龙
	 * */
	public List<T> selectByQueryMap(Map<String, Object> queryMap,Object cls,PagingBean pb)throws TransactionException{
		if(pb==null){
			return this.getDAO().findByHql(this.getHQL(queryMap , cls),null);
		}else{
			return this.getDAO().findByHql(this.getHQL(queryMap , cls),null , pb);
		}
	}
	
	/**
	 * 通过Map取得HQL查询语句
	 * <p>
	 * @param map
	 * 例：map.put("and param.like","%value%")
	 * <br>属性名.=	等于	
	 * <br>属性名.<>	不等于
	 * <br>属性名.like 模糊查询
	 * <br>属性名.in 	  
	 * <br>属性名.orderBy	排序 
	 * @param cls	实体类对象		例：ClassObject.class
	 * </p>
	 * @return 返回HQL语句
	 * */
	public String getHQL(Map<String, Object> map,Object cls){
		StringBuffer hql = new StringBuffer("from Object where 1=1 ");
		Class<?> cs = (Class)cls;
		hql.replace(5, 11, cs.getSimpleName()); // 替换类名
		if(!map.isEmpty()){
			Iterator itor = map.keySet().iterator();
			while (itor.hasNext()) {
				String key = (String) itor.next();
				Object o = map.get(key);
				if(key.toUpperCase().contains(".=")){
					hql.append(key.substring(0,key.lastIndexOf(".=")));
					hql.append(" = ");
					hql.append(o instanceof Integer?map.get(key):("'"+map.get(key)+"' "));
				}else if(key.toUpperCase().contains(".<>")){
					hql.append(key.substring(0,key.lastIndexOf(".<>")));
					hql.append(" <> ");
					hql.append(o instanceof Integer?map.get(key):("'"+map.get(key)+"' "));
				}else if(key.toUpperCase().contains(".LIKE")){
					hql.append(key.substring(0,key.lastIndexOf(".like")));
					hql.append(" LIKE ");
					hql.append("'"+map.get(key)+"' ");				
				}else if(key.toUpperCase().contains(".IN")){
					hql.append(key.substring(0,key.lastIndexOf(".in")));
					hql.append(" IN(");
					hql.append(map.get(key)+") ");
				}else if(!key.toUpperCase().contains("ORDERBY")){
					//非排序关键字
					hql.append(" "+key+" "+map.get(key));
				}
			}
			//拼接排序
			if(!Utils.show(map.get("orderBy")).equals("")){
				hql.append(" order by ");
				hql.append(map.get("orderBy"));
			}
		}
		// 最后一个属性设置完成之后取出残余的and和尾部的空格。
		if (hql.toString().endsWith("and ")) {
			hql.delete(hql.length() - "and".length() - 1, hql.length());
		}
		// 如果没有设置任何属性，则取出尾部的where字符串和后面的空格。
		if (hql.toString().endsWith("where ")) {
			hql.delete(hql.length() - "where".length() - 1, hql.length());
		}
		return hql.toString();
	}

	/**
	 * 反射取得HQL查询语句
	 * @param bean 待查询的Bean，使用前如果为空需要实例化Bean
	 * @return 返回HQL语句
	 * */
	public String getHQL(Object bean) {
		StringBuffer hql = new StringBuffer("from Object where ");
		Class<?> beanClass = bean.getClass();// 取得类名
		hql.replace(5, 11, beanClass.getSimpleName()); // 替换类名
		Field[] field = bean.getClass().getDeclaredFields(); // 取得该类所有的属性
		for (Field fie : field) {
			try {
				PropertyDescriptor pd = new PropertyDescriptor(fie.getName(),beanClass);
				Method getMethod = pd.getReadMethod();// 取得类方法
				Object objTemp = getMethod.invoke(bean);// 取得该方法的值
				// 略过null的属性值
				if (objTemp == null || objTemp.toString().equals("")) {
					continue;
				}
				hql.append(fie.getName() + " like '%" + objTemp + "%'");
				hql.append(" and ");
			} catch (IntrospectionException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		// 最后一个属性设置完成之后取出残余的and和尾部的空格。
		if (hql.toString().endsWith("and ")) {
			hql.delete(hql.length() - "and".length() - 1, hql.length());
		}
		// 如果没有设置任何属性，则取出尾部的where字符串和后面的空格。
		if (hql.toString().endsWith("where ")) {
			hql.delete(hql.length() - "where".length() - 1, hql.length());
		}
		return hql.toString();
	}

}
